Projekt Pronal Projekt Pronal

Kazalo:
Sofinasiranje projekta
Starejši - zbirka nalog...
Tekmovanja...
Tekmovanja - dopolni...
Tekmovanja - Parsons...
Tekmovanja - popravi...
Starejši - učbenik
Funkcije
If stavek
Izpisi
Množice
Nizi
Pisanje in popravljanje programa
Seznami in nizi
Slovarji
Spoznajmo Python
Uvod v funkcije
Zanka for
Zanka while
Uvod v funkcije

Uvod v funkcije


Definicija funkcije - razlaga

V Pythonu definiramo funkcijo takole:

def ime_funkcije(x, y, ..., z):
    ukaz
    ukaz
    ...
    ukaz
    return rezultat_funkcije

Spremenljivkam x, y, ..., z rečemo argumenti funkcije. Rezultat funkcije vrnemo s stavkom return.

Poglejmo primer enostavne funkcije, ki sprejme števili x in y ter vrne njuno vsoto:

def vsota(x, y):
    return x + y

Če želimo s pomočjo funkcije vsota izračunati vsoto števil $3$ in $5$, funkcijo pokličemo z argumentoma $3$ in $5$, kar nam kot rezultat vrne število $8$:

>>> vsota(3, 5)
8

Definiramo lahko tudi funkcijo, ki ne sprejme nobenega argumenta. Primer take funkcije je spodnja funkcija, ki ob vsakem klicu vrne število $3$.

def fun_brez_arg():
    return 3

>>> fun_brez_arg()
3

Definicija funkcije

V "Definicija funkcije - razlaga" si lahko preberete, kako v Pythonu definiramo funkcije.

Tu pa rešite nekaj osnovnih nalog iz te teme.

1. podnaloga

Mama Mojca vsak mesec nekaj denarja, ki ga dobi od pokojnine, prihrani za žepnino za svojega vnuka Jana. Napišite funkcijo zepnina(pokojnina, odstotek). Funkcija sprejme višino Mojčine mesečne pokojnine v evrih in odstotek, ki pove, koliko odstotkov svoje pokojnine bo Mojca ta mesec prihranila za Jana. Funkcija naj vrne višino žepnine v evrih, ki jo bo prejel Jan. Zgled:

>>> zepnina(800, 0.03)
24.0
>>> zepnina(823, 0.05)
41.150000000000006

Uradna rešitev

def zepnina(pokojnina, odstotek):
    """Vrne odstotek pokojnine v evrih."""
    return pokojnina * odstotek

2. podnaloga

Napišite funkcijo zepnina2(pokojnina, odstotek). Funkcija naj, tako kot zgornja, sprejme višino Mojčine mesečne pokojnine v evrih in odstotek, ki pove, koliko odstotkov svoje pokojnine bo Mojca ta mesec prihranila za Jana. Funkcija naj vrne višino žepnine v evrih, ki jo bo prejel Jan. Tokrat naj bo rezultat zaokrožen na $2$ decimalni mesti natančno. Pri zaokroževanju si pomagajte z vgrajeno funkcijo round - dokumentacija.

>>> zepnina2(800, 0.03)
24.0
>>> zepnina2(823, 0.05)
41.15

Uradna rešitev

def zepnina2(pokojnina, odstotek):
    """Vrne odstotek pokojnine v evrih zaokrožen na dve decimalni mesti."""
    return round(pokojnina * odstotek, 2)

3. podnaloga

Napišite funkcijo ostane(penzija, odstotek), ki tako kot prejšnja sprejme višino Mojčine mesečne pokojnine v evrih in odstotek, ki pove koliko odstotkov svoje pokojnine bo Mojca ta mesec prihranila za Jana. Tokrat naj namesto višine žepnine, ki jo prejme Jan, vrne količino denarja, ki ostane Mojci potem, ko da Janu žepnino. Znesek naj bo zaokrožen na $2$ decimalni mesti natančno.

>>> ostane(800, 0.03)
776.0
>>> ostane(823, 0.04)
790.08

Uradna rešitev

def ostane(pokojnina, odstotek):
    """Vrne razliko med prvotno pokojino ter pokojnino pomnoženo z danim odstotkom.
       Rezultat je zaokrožen na dve decimalni mesti."""
    return round(pokojnina -  pokojnina*odstotek, 2)

4. podnaloga

Mojca zadnje čase opaža, da vsak mesec dobi malce drugačen znesek pokojnine kot prejšnji mesec. Pomagajte ji ugotoviti, za koliko se njene pokojnine med zaporednimi meseci razlikujejo. Sestavite funkcijo razlika(prva, druga), ki sprejme števili prva in druga. Števili predstavljata zneska pokojnine v poljubnih dveh mesecih. Funkcija naj vrne njuno razliko. Zgled:

>>> razlika(900, 850)
50
>>> razlika(600, 700)
-100

Uradna rešitev

def razlika(prva, druga):
    """Vrne razliko med prvo in drugo pokojnino."""
    return prva - druga

Funkcije, ki vračajo več kot le eno vrednost - razlaga

Poglejmo primer funkcije, ki sprejme tri števila u, v in x, ter vrne števili u in v povečani za vrednost x.

def povecaj(u, v, x):
    return u + x, v + x

Če sedaj to funkcijo pokličemo,

>>> povecaj(6, 8, 3)
(9, 11)

opazimo, da smo rezultat funkcije dobili v obliki urejenega para števil oziroma terke.

Shranimo rezultat funkcije v spremenljivko rezultat:

rezultat = povecaj(6, 8, 3)
>>> rezultat
(9, 11)

Ker se v Pythonu številčenje elementov znotraj terk in seznamov začne z 0, do prvega elementa terke dostopamo z ukazom:

>>> rezultat[0]
9

Do drugega elementa pa z ukazom:

>>> rezultat[1]
11

Funkcije, ki vračajo več kot le eno vrednost

V "Funkcije, ki vračajo več kot le eno vrednost - razlaga" si lahko preberete, kako v Pythonu definiramo funkcije, ki vračajo več vrednosti in kako do teh vrednosti dostopamo.

Tu pa rešite nekaj osnovnih nalog iz te teme.

1. podnaloga

Mojca vsako nedeljo zjutraj speče n piškotov. Ob nedeljah pridejo na obisk njeni $3$ vnuki, ki pojedo vsak enako število piškotov, ponavadi pa jih nekaj ostane tudi za ata Janeza. Da bo Mojca hitreje izračunala, koliko piškotov dobi vsak vnuk in koliko jih ostane za ata Janeza, napišite funkcijo razdeli_piskote(n), ki sprejme število spečenih piškotov, vrne pa urejen par števil - prvo pove, koliko piškotov dobi vsak vnuk, drugo pa, koliko piškotov ostane za Janeza.

>>> razdeli_piskote(7):
(2, 1)
>>> razdeli_piskote(54)
(18, 0)

Uradna rešitev

def razdeli_piskote(n):
    """Vrne urejen par števil - prvo predstavlja celi del pri deljenju števila n s
       3, drugo pa ostanek pri deljenju števila n s 3."""
    return n//3, n%3

2. podnaloga

Mojci včasih ostane še nekaj piškotov od prejšnjega tedna. To se zgodi, kadar ata Janez ne poje vseh piškotov, ki so mu bili namenjeni. Kadar se to zgodi, je Mojca hudo užaljena in mu tudi prihodnji teden ne pusti jesti piškotov. Ob takih tednih je ona tista, ki poje piškote, ki jih pustijo njeni trije vnuki, prav tako pa poje tudi piškote od prejšnjega tedna.

Napišite funkcijo razdeli_piskote_drugace(n, ostane), ki sprejme število na novo spečenih piškotov in število piškotov, ki so ostali od prejšnjega tedna, ter zopet vrne urejen par števil - prvo pove, koliko piškotov dobi vsak izmed vnukov, drugo pa, koliko piškotov ostane za Mojco.

>>> razdeli_piskote_drugace(7, 2):
(2, 3)
>>> razdeli_piskote_drugace(54, 1)
(18, 1)

Uradna rešitev

def razdeli_piskote_drugace(n, ostane):
    """Vrne urejen par števil - prvo predstavlja celi del pri deljenju števila n s
       3, drugo pa ostanek pri deljenju števila n s 3, kateremu je prišteta
       vrednost spremenljivke ostane."""
    return n//3, ostane + n%3

Lokalne spremenljivke in lokalne funkcije - razlaga

Poglejmo naslednjo funkcijo:
def sestej_odstej_in_zmnozi(x, y):
    a = x + y
    b = x - y
    return a * b

Spremenljivkama a in b rečemo lokalni spremenjivki . To pomeni, da obstajata le znotraj funkcije, navzven pa nista vidni. Če imamo zunaj funkcije definirane še kake druge spremenljivke z istimi imeni, se te spremenljivke med seboj ne bodo mešale.

Poglejmo delovanje naslednjega programa:

a = 7
y = 9
def kekec(x):
    a = 2*x + 1
    return a

def mojca(x):
    a = 2*x - 1
    b = kekec(a)
    return a + b

Kaj vrne klic funkcije mojca(3)?

Kot smo povedali prej, so lokalne spremenljivke v funkciji vidne samo znotraj funkcije. Spremenljivka a iz funkcije mojca torej nikakor ni povezana z zunaj funkcije definirano spremenljivko a in niti s spremenljivko a iz funkcije kekec.

Pojdimo po vrsti. Pri klicu mojca(3) dobi spremenljivka x iz funkcije mojca vrednost $3$, v naslednji vrstici pa dobi spremenljivka a vrednost $5$. V naslednji vrstici se nato kliče funkcija kekec z argumentom $5$. Pri klicu kekec(5) dobi spremenljivka a iz funkcije kekec vrednost $11$, kar funkcija nato tudi vrne. Rezultat klica kekec(5) je torej $11$, kar se shrani v spremenljivko b iz funkcije mojca. Funkcija nato vrne seštevek spremenljivk a in b, kar znaša $16$. Spodaj je prikazan potek programa po korakih:

a = 7
y = 9
def kekec(x):      # (4. korak: x = 5)
    a = 2*x + 1    # (5. korak: a = 11)
    return a       # (6. korak: kekec(5) = 11)

def mojca(x):      # (1. korak: x = 3)
    a = 2*x - 1    # (2. korak: a = 5)
    b = kekec(a)   # (3. korak -> 4. korak -> 5. korak -> 6. korak: b = 11)
    return a + b   # (7. korak: mojca(3) = a + b = 5 + 11 = 16)

>>> mojca(3)
16

Funkcijo mojca bi lahko recimo poklicali tudi z vrednostjo $9$, torej mojca(9) ali pa kar mojca(y), saj je v programu, zunaj funkcije, definirana spremenljivka y, ki ima vrednost $9$. Rezultat tega klica bi bil $52$.

Kaj pa bi bil rezultat klica mojca(a)?

Rezultat bi bil $40$ po enakem postopku kot prej. Spremenljivka a je le spremenljivka, definirana zunaj funkcije in se ne meša z isto imensko lokalno spremenljivko. Klic mojca(a) je ekvivalenten klicu mojca(7).

Poleg lokalnih spremenljivk, lahko funkcije vsebujejo tudi lokalne funkcije. To so funkcije, ki obstajajo le znotraj funkcij in navzven niso vidne.

Poglejmo primer funkcije, ki vsebuje lokalno funkcijo:

def rozle(x):
    def bedanec(y):
        return x + y
    return bedanec(10) + 1

Kaj vrne klic rozle(5)?

Pa poglejmo:

def rozle(x):               # (1. korak: x = 5)
    def bedanec(y):         # (3. korak: y = 10)
        return x + y        # (4. korak: bedanec(10) = x + y = 5 + 10 = 15)
    return bedanec(10) + 1  # (2. korak -> 3. korak -> 4. korak: rozle(5) = 15 + 1 = 16)

>>> rozle(5)
16
Mesto objave ob koncu projekta 15.9.2018